﻿using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using TrackSystem.Contracts;
using TrackSystem.Entities.Dtos.Equip;
using TrackSystem.Entities.Dtos.Logic;
using TrackSystem.Entities.Dtos.Loop;
using TrackSystem.Entities.Extensions;
using TrackSystem.Entities.RequestFeatures;


namespace TrackSystem.UI.Server.Pages.Configuration
{
    public partial class LoopDefTable
    {
        private IEnumerable<LoopDto> _loopDtos = [];
        private readonly ConcurrentDictionary<int, bool> _dictChanges = new();
        private string _sMsg = "";

        [Required]
        private HubConnection hubConnection;

        private bool bInsertFlag = false;
        private LoopDto? addedLoop;
        private IEnumerable<SelectedItem> equipList = Array.Empty<SelectedItem>();
        private IEnumerable<SelectedItem> PVNameItems = Array.Empty<SelectedItem>();
        private IEnumerable<SelectedItem> SVNameItems = Array.Empty<SelectedItem>();

        // Page Parameter
        private RequestParameter pageParms = new RequestParameter();
        private int MaxPageNumber = 1;
        private static IEnumerable<SelectedItem> PageItemsSource =
            [
                new("2", "2条/页"),
                new("4", "4条/页"),
                new("10", "10条/页"),
                new("20", "20条/页")
            ];

        private static IEnumerable<SelectedItem> LoopMethodItems =
        [
                new("0", "PID"),
                new("1", "FUZZY"),
                new("2", "Network"),
            ];

        private int PageItems { get; set; } = 4;
        private string PageInfoText => $"每页 {PageItems} 条 共 {MaxPageNumber} 页";

        [Inject]
        [NotNull]
        private ToastService? ToastService { get; set; }

        /// <summary>
        /// 初始化函数
        /// </summary>
        /// <param name="firstRender"></param>
        /// <returns></returns>
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {

            if (firstRender)
            {
                pageParms = new RequestParameter
                {
                    PageNumber = 1,
                    PageSize = PageItems,
                    QueryString = ""
                };

                await SignalServer(pageParms);

                try
                {
                    hubConnection.On<List<string>>("RecvPVNames", (result) =>
                    {
                        PVNameItems = result.Select(c => new SelectedItem(c, c)).ToList();
                        _sMsg = $"{DateTime.Now} RecvPVNames SignalR success!";
                        InvokeAsync(StateHasChanged);
                    });

                    await hubConnection.SendAsync("GetPVNames");

                    hubConnection.On<List<string>>("RecvSVNames", (result) =>
                    {
                        SVNameItems = result.Select(c => new SelectedItem(c, c)).ToList();
                        _sMsg = $"{DateTime.Now} RecvSVNames SignalR success!";
                        InvokeAsync(StateHasChanged);
                    });

                    await hubConnection.SendAsync("GetSVNames");
                }
                catch (Exception e)
                {
                    _sMsg = e.Message;
                }

                await GetEquipInfoAsync();
            }
        }

        /// <summary>
        /// 获取所有逻辑表达式
        /// </summary>
        /// <returns></returns>
        private async Task SignalServer(RequestParameter parameter)
        {
            try
            {
                if (hubConnection == null || hubConnection.State == HubConnectionState.Disconnected)
                {
                    // 建立SIGNALR连接
                    hubConnection = new HubConnectionBuilder()
                        .WithUrl("http://localhost:5000/loophub")
                        .WithAutomaticReconnect([TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3)])
                        .Build();

                    await hubConnection.StartAsync();
                }

                // 发送请求
                hubConnection.On<IEnumerable<LoopDto>, int, int>("ReceivePagedLoops",
                    (result, curPage, totalPages) =>
                {
                    _loopDtos = result;
                    foreach (var item in _loopDtos)
                    {
                        if (!_dictChanges.ContainsKey(item.Id))
                        {
                            _dictChanges.TryAdd(item.Id, true);
                        }
                    }
                    pageParms.PageNumber = curPage;
                    MaxPageNumber = totalPages;
                    _sMsg = $"{DateTime.Now} ReceivePagedLogics SignalR success!";
                    InvokeAsync(StateHasChanged);
                });

                await hubConnection.SendAsync("GetPagedLoops", parameter);
            }
            catch (Exception ex)
            {
                _sMsg = ex.ToString();
            }
        }

        /// <summary>
        /// 切换到编辑状态
        /// </summary>
        /// <param name="id">逻辑表达式的ID号</param>
        /// <returns></returns>
        private async Task OnSwitchToChanged(int id)
        {
            if (_dictChanges.ContainsKey(id))
            {
                _dictChanges[id] = false;
                await GetEquipInfoAsync();
            }
        }

        /// <summary>
        /// 保存编辑内容
        /// </summary>
        /// <param name="dto">逻辑表达式视图</param>
        /// <returns></returns>
        private async Task OnAcceptChanged(LoopDto dto)
        {
            if (_dictChanges.ContainsKey(dto.Id))
            {
                hubConnection.On<ApiResult<LogicDto>>("RecvUpdateLoop", (content) =>
                {
                    _sMsg = $"{DateTime.Now} RecvUpdateLogic Singal Request";
                    InvokeAsync(async () =>
                    {
                        if (content.Success)
                        {
                            _dictChanges[dto.Id] = true;
                            await ToastService.Success("通道列表", "更新成功");
                            await SignalServer(pageParms);
                        }
                        else
                        {
                            await ToastService.Error("通道列表", content.Message);
                        }
                    });
                });

                await hubConnection.SendAsync("UpdateLoopAsync", dto);
            }
        }

        /// <summary>
        /// 取消编辑内容
        /// </summary>
        /// <param name="dto">逻辑表达式视图</param>
        /// <returns></returns>
        private async Task OnRefuseChanged(LoopDto dto)
        {
            if (_dictChanges.ContainsKey(dto.Id))
            {
                await SignalServer(pageParms);

                _dictChanges[dto.Id] = true;
                StateHasChanged();
            }
        }

        /// <summary>
        /// 获取装备列表
        /// </summary>
        /// <returns></returns>
        private async Task GetEquipInfoAsync()
        {
            hubConnection.On<IEnumerable<EquipDto>>("RecvEquips", (content) =>
            {
                _sMsg = $"{DateTime.Now} RecvEquips Singal Request";
                equipList = [.. content.Select(c => new SelectedItem(c.Id.ToString(), c.Name))];
                InvokeAsync(StateHasChanged);
            });

            await hubConnection.SendAsync("GetEquipsAsync");
        }

        /// <summary>
        /// 切换到插入模式
        /// </summary>
        /// <returns></returns>
        private async Task OnSwitchToInsert()
        {
            hubConnection.On<int>("RecvMaxId", (maxId) =>
            {
                _sMsg = $"{DateTime.Now} RecvMaxId Singal Request";
                addedLoop = new LoopDto
                {
                    Name = "Loop" + (maxId + 1),
                    Description = "新建控制回路",
                    PVName = PVNameItems.FirstOrDefault()?.Value ?? string.Empty,
                    SVName = SVNameItems.FirstOrDefault()?.Value ?? string.Empty,
                    OPName = SVNameItems.FirstOrDefault()?.Value ?? string.Empty,
                    equipId = int.Parse(equipList.FirstOrDefault()?.Value ?? "1"),
                    Method = LoopMethod.PID,
                    Params_P = 1,
                    Params_I = 0,
                    Params_D = 0,
                    Action = true,
                    Dirction = true,
                    OutHLimit = 100,
                    OutLLimit = -100,
                    PDeadZone = 10,
                    NDeadZone = 10,
                };
                bInsertFlag = true;
                InvokeAsync(StateHasChanged);
            });
            await hubConnection.SendAsync("GetMaxId");
        }

        /// <summary>
        /// 保存插入的逻辑表达式
        /// </summary>
        /// <returns></returns>
        private async Task OnAcceptInsert()
        {
            hubConnection.On<ApiResult<LoopDto>>("RecvInsertLoop", (content) =>
            {
                _sMsg = $"{DateTime.Now} RecvInsertLoop Singal Request";
                InvokeAsync(async () =>
                {
                    if (content.Success)
                    {
                        bInsertFlag = false;
                        await ToastService.Success("控制回路", "添加成功");
                    }
                    else
                    {
                        await ToastService.Error("控制回路", content.Message);
                    }
                    await SignalServer(pageParms);
                });
            });

            await hubConnection.SendAsync("InsertLoopAsync", addedLoop);
        }

        /// <summary>
        /// 取消插入的逻辑表达式
        /// </summary>
        /// <returns></returns>
        private Task OnRefuseInsert()
        {
            bInsertFlag = false;
            StateHasChanged();
            return Task.CompletedTask;
        }

        /// <summary>
        /// 删除逻辑表达式
        /// </summary>
        /// <param name="id">逻辑表达式ID号</param>
        /// <returns></returns>
        private async Task OnDeleteLoop(int id)
        {
            if (_dictChanges.ContainsKey(id))
            {

                hubConnection.On<ApiResult<LogicDto>>("RecvDeleteLoop", (content) =>
                {
                    _sMsg = $"{DateTime.Now} RecvDeleteLoop Singal Request";
                    InvokeAsync(async () =>
                    {
                        if (content.Success)
                        {
                            _dictChanges.Remove(id, out _);
                            await ToastService.Success("控制回路", "删除成功");
                            pageParms.PageNumber = 1;
                            await SignalServer(pageParms);
                        }
                        else
                        {
                            await ToastService.Error("控制回路", content.Message);
                        }
                    });
                });
                await hubConnection.SendAsync("DeleteLoopAsync", id);
            }
        }


        // ----------------------------------------------------------
        private async Task OnPageClick(int n)
        {
            pageParms.PageNumber = n;
            await SignalServer(pageParms);
        }

        private async Task OnPageItemsChanged(SelectedItem item)
        {
            pageParms.PageSize = int.Parse(item.Value);
            pageParms.PageNumber = 1;
            await SignalServer(pageParms);
        }
    }
}
